package org.itheima.game.org.tank.game

import javafx.scene.input.KeyCode
import javafx.scene.input.KeyEvent
import org.itheima.game.org.tank.game.business.*
import org.itheima.game.org.tank.game.enum.Direction
import org.itheima.game.org.tank.game.model.*
import org.itheima.kotlin.game.core.Painter
import org.itheima.kotlin.game.core.Window
import java.io.File
import java.util.concurrent.CopyOnWriteArrayList

/**
 * description ： 主窗体
 * author : chenmengjia
 * email : cmjsp1990@163.com
 * date : 2020/3/14 13:55
 */
class GameWindow :
    Window(title = "坦克大战2020.1.0版本", icon = "img/logo.jpg", width = Config.gameWidth, height = Config.gameHeight) {
    //管理元素集合
    private val viewsList = CopyOnWriteArrayList<View>()
    private lateinit var tank: Tank
    private var gameOver: Boolean = false
    private var enemyTotalSize = 20
    private var enemyActiveSize = 6
    //出生地
    private var enemyBornLocation = arrayListOf<Pair<Int, Int>>()
    private var bornIndex = 0

    override fun onCreate() {
        //地图
        val file = File(javaClass.getResource("/map/1.map").path)
        val readLines = file.readLines()
        var lineNum = 0;
        readLines.forEach {
            var columnNum = 0;
            it.toCharArray().forEach {
                when (it) {
                    '砖' -> viewsList.add(Wall(columnNum * Config.block, lineNum * Config.block))
                    '铁' -> viewsList.add(Steel(columnNum * Config.block, lineNum * Config.block))
                    '水' -> viewsList.add(Water(columnNum * Config.block, lineNum * Config.block))
                    '草' -> viewsList.add(Grass(columnNum * Config.block, lineNum * Config.block))
                    '敌' -> enemyBornLocation.add(Pair(columnNum * Config.block, lineNum * Config.block))

                }
                columnNum++
            }
            lineNum++
        }
        //添加我方的坦克
        tank = Tank(Config.block * 10, Config.block * 12)
        viewsList.add(tank)
        viewsList.add(Camp(Config.gameWidth / 2 - Config.block, Config.gameHeight - 96 - 50))

    }

    override fun onDisplay() {
        //绘制图像
        //绘制一个砖墙
        //Painter.drawImage("img/grass.gif", 200, 200)
        //绘制地图
        viewsList.forEach {
            it.draw()
        }


    }

    override fun onKeyPressed(event: KeyEvent) {
        if (!gameOver) {


            when (event.code) {
                KeyCode.W -> {
                    tank.move(Direction.UP)

                }
                KeyCode.S -> {
                    tank.move(Direction.DOWN)

                }
                KeyCode.A -> {
                    tank.move(Direction.LEFT)

                }
                KeyCode.D -> {
                    tank.move(Direction.RIGHT)

                }
                KeyCode.J -> {
                    val bullet = tank.shoot()
                    viewsList.add(bullet)
                }

            }
        }
    }

    override fun onRefresh() {
        //检测自动销毁
        viewsList.filter {
            it is Destroyable
        }.forEach {
            if ((it as Destroyable).isDestroyed()) {
                viewsList.remove(it)
                if (it is Enemy) {
                    enemyTotalSize--
                }
                val showDestroy = it.showDestroy()
                showDestroy?.let {
                    viewsList.addAll(showDestroy)
                }
            }

        }
        if (gameOver) {
            return
        }
        //业务逻辑
        //判断运动的物体和阻塞物体是否碰撞
        viewsList.filter { it is Movable }.forEach { move ->
            //找到阻塞
            move as Movable
            var badDirection: Direction? = null
            var badBlockable: Blockable? = null
            //不要和自己比较
            viewsList.filter { (it is Blockable) and (move != it) }.forEach blockTag@{ block ->
                //遍历集合，找到是否发生碰撞
                //move和block是否碰撞

                block as Blockable
                val direction = move.willCollision(block)
                direction?.let {
                    //移动的发生碰撞，跳出当前
                    badDirection = direction
                    badBlockable = block
                    return@blockTag
                }

            }
            //找到阻塞，找到碰撞的方向
            //通知
            move.notifyCollision(badDirection, badBlockable)


        }

        //检测自动移动
        viewsList.filter {
            it is AutoMovable
        }.forEach {
            (it as AutoMovable)
                .autoMove()
        }

        //检测具备攻击能力是否产生碰撞

        viewsList.filter { it is Attackable }.forEach { attack ->
            attack as Attackable
            //受攻击方不能使自己
            //攻击方也是受攻击方
            viewsList.filter { (it is Sufferable) and (attack.owner != it) and (attack != it) }
                .forEach sufferTag@{ suffer ->
                    suffer as Sufferable
                    //判断是否发生碰撞
                    if (attack.isCollision(suffer)) {
                        //通知攻击者
                        attack.notifyAttack(suffer)
                        //通知被攻击者
                        val sufferView = suffer.notifySuffer(attack)
                        sufferView?.let {
                            viewsList.addAll(sufferView)
                        }

                        return@sufferTag
                    }
                }

        }
        //检测自动射击
        viewsList.filter { it is AutoShot }.forEach {
            it as AutoShot
            val shot = it.autoShot()
            shot?.let {
                viewsList.add(shot)
            }
        }
        if ((viewsList.filter { it is Camp }.isEmpty()) or (enemyTotalSize <= 0)) {
            gameOver = true
        }
        //检测地敌方出生
        //小于激活数
        if ((enemyTotalSize > 0) and (viewsList.filter { it is Enemy }.size < enemyActiveSize)) {
            val index = bornIndex % enemyBornLocation.size
            val pair = enemyBornLocation[index]
            viewsList.add(Enemy(pair.first, pair.second))
            bornIndex++
        }

    }
}